//package org.example;
//
//import java.io.*;
//import java.nio.ByteBuffer;
//import java.nio.channels.*;
//import java.nio.file.*;
//import java.util.*;
//import java.util.concurrent.*;
//import java.util.concurrent.atomic.AtomicLong;
//
//public class FileQueue11<T> {
//    // 队列根目录
//    private final String baseDir;
//    // 每个片段文件的最大元素数
//    private final int segmentSize;
//    // 序列化器
//    private final Serializer<T> serializer;
//    // 读写指针
//    private final AtomicLong readPosition = new AtomicLong(0);
//    private final AtomicLong writePosition = new AtomicLong(0);
//    // 定时清理任务
//    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
//    // 文件锁
//    private final FileLock lock;
//
//    // 构造函数
//    public FileQueue11(String baseDir, int segmentSize, Serializer<T> serializer) throws IOException {
//        this.baseDir = baseDir;
//        this.segmentSize = segmentSize;
//        this.serializer = serializer;
//
//        // 初始化目录
//        Files.createDirectories(Paths.get(baseDir));
//
//        // 加载指针位置
//        loadPositions();
//
//        // 获取锁文件
//        File lockFile = new File(baseDir, ".lock");
//        lock = new RandomAccessFile(lockFile, "rw").getChannel().lock();
//
//        // 启动定时清理任务（每小时执行一次）
//        scheduler.scheduleAtFixedRate(this::cleanup, 1, 1, TimeUnit.HOURS);
//    }
//
//    // 入队操作
//    public void enqueue(T element) throws IOException {
//        long position = writePosition.getAndIncrement();
//        Path segmentFile = getSegmentFile(position);
//
//        // 序列化元素
//        byte[] data = serializer.serialize(element);
//
//        // 写入文件（格式：4字节长度 + 数据）
//        try (FileChannel channel = FileChannel.open(segmentFile, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
//            ByteBuffer buffer = ByteBuffer.allocate(4 + data.length);
//            buffer.putInt(data.length);
//            buffer.put(data);
//            buffer.flip();
//
//            // 计算写入位置
//            long offset = (position % segmentSize) * (4 + data.length); // 简化计算，实际应记录准确偏移量
//            channel.write(buffer, offset);
//        }
//
//        // 保存指针位置
//        savePositions();
//    }
//
//    // 出队操作
//    public T dequeue() throws IOException {
//        long position = readPosition.get();
//        if (position >= writePosition.get()) {
//            return null; // 队列为空
//        }
//
//        Path segmentFile = getSegmentFile(position);
//        if (!Files.exists(segmentFile)) {
//            return null;
//        }
//
//        // 读取元素
//        T element = null;
//        try (FileChannel channel = FileChannel.open(segmentFile, StandardOpenOption.READ)) {
//            // 计算读取位置
//            long offset = (position % segmentSize) * 1024; // 假设最大元素大小为1020字节
//            ByteBuffer lenBuffer = ByteBuffer.allocate(4);
//
//            if (channel.read(lenBuffer, offset) == 4) {
//                lenBuffer.flip();
//                int dataLength = lenBuffer.getInt();
//
//                ByteBuffer dataBuffer = ByteBuffer.allocate(dataLength);
//                if (channel.read(dataBuffer, offset + 4) == dataLength) {
//                    dataBuffer.flip();
//                    element = serializer.deserialize(dataBuffer.array());
//
//                    // 移动读指针
//                    readPosition.incrementAndGet();
//                    savePositions();
//                }
//            }
//        }
//
//        return element;
//    }
//
//    // 定时清理
//    private void cleanup() {
//        try {
//            long readSeg = getSegmentNumber(readPosition.get());
//            long writeSeg = getSegmentNumber(writePosition.get());
//
//            // 删除已完全读取的片段
//            for (long i = 0; i < readSeg; i++) {
//                Path segFile = getSegmentFile(i * segmentSize);
//                Files.deleteIfExists(segFile);
//            }
//
//            // 合并部分读取的片段（如果需要）
//            if (readSeg < writeSeg) {
//                mergeSegments(readSeg);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//
//    // 合并片段
//    private void mergeSegments(long segNumber) throws IOException {
//        Path sourceFile = getSegmentFile(segNumber * segmentSize);
//        Path tempFile = Paths.get(baseDir, "temp_" + segNumber);
//
//        try (FileChannel sourceChannel = FileChannel.open(sourceFile, StandardOpenOption.READ);
//             FileChannel tempChannel = FileChannel.open(tempFile, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
//
//            long startPos = readPosition.get() % segmentSize;
//            long remaining = segmentSize - startPos;
//
//            // 仅复制未读取的数据
//            ByteBuffer buffer = ByteBuffer.allocateDirect(8192);
//            long position = startPos * 1024; // 假设每个元素占用1024字节
//
//            while (remaining > 0) {
//                int bytesRead = sourceChannel.read(buffer, position);
//                if (bytesRead == -1) break;
//
//                buffer.flip();
//                tempChannel.write(buffer);
//                position += bytesRead;
//                remaining -= bytesRead / 1024;
//                buffer.clear();
//            }
//        }
//
//        // 替换原文件
//        Files.delete(sourceFile);
//        Files.move(tempFile, sourceFile);
//
//        // 调整指针
//        readPosition.set(segNumber * segmentSize);
//        savePositions();
//    }
//
//    // 获取片段文件
//    private Path getSegmentFile(long position) {
//        long segNumber = getSegmentNumber(position);
//        return Paths.get(baseDir, "segment_" + segNumber);
//    }
//
//    // 获取片段编号
//    private long getSegmentNumber(long position) {
//        return position / segmentSize;
//    }
//
//    // 加载指针位置
//    private void loadPositions() throws IOException {
//        Path posFile = Paths.get(baseDir, "positions.dat");
//        if (Files.exists(posFile)) {
//            try (DataInputStream dis = new DataInputStream(new FileInputStream(posFile.toFile()))) {
//                readPosition.set(dis.readLong());
//                writePosition.set(dis.readLong());
//            }
//        }
//    }
//
//    // 保存指针位置
//    private void savePositions() throws IOException {
//        Path posFile = Paths.get(baseDir, "positions.dat");
//        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(posFile.toFile()))) {
//            dos.writeLong(readPosition.get());
//            dos.writeLong(writePosition.get());
//        }
//    }
//
//    // 关闭队列
//    public void close() throws IOException {
//        scheduler.shutdown();
//        lock.release();
//    }
//
//    // 序列化接口
//    public interface Serializer<T> {
//        byte[] serialize(T obj);
//        T deserialize(byte[] data);
//    }
//}
